package com.fly.procode.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.fly.procode.core.DateUtil;
import com.fly.procode.core.Service;

/*
 * Swing技术实现
 */
public class ProCodeToolFrame extends JFrame
{
    private static final long serialVersionUID = 965289280779529771L;
    
    // 设置窗口风格的菜单
    JCheckBoxMenuItem windows = new JCheckBoxMenuItem("Windows", true);
    
    JCheckBoxMenuItem metal = new JCheckBoxMenuItem("Metal");
    
    // 构造
    public ProCodeToolFrame()
    {
        // 加载图标
        URL imgURL = this.getClass().getResource("/image/icon.gif");
        if (imgURL != null)
        {
            Image image = Toolkit.getDefaultToolkit().createImage(imgURL);
            setIconImage(image);
        }
        setTitle("代码备份恢复工具 V1.1.0");
        // 设置宽高
        setSize(540, 340);
        // 得到当前系统screenSize
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        // 得到当前frameSize
        Dimension frameSize = this.getSize();
        
        // 自适应处理
        if (frameSize.height > screenSize.height)
        {
            frameSize.height = screenSize.height;
        }
        if (frameSize.width > screenSize.width)
        {
            frameSize.width = screenSize.width;
        }
        
        setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
        addMenu();
        add(new TabPanePanel());
        setWindowStyle("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        setResizable(false);
        setVisible(true);
        // 窗口关闭监听器
        addWindowListener(new WindowAdapter()
        {
            @Override
            public void windowClosing(WindowEvent e)
            {
                System.exit(0);
            }
        });
    }
    
    // Menu set
    private void addMenu()
    {
        JMenuBar mb = new JMenuBar();
        // 菜单1
        JMenu windowStyle = new JMenu("窗口风格");
        windows.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent actionevent)
            {
                String plaf = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
                setWindowStyle(plaf);
                windows.setState(true);
                metal.setState(false);
            }
        });
        
        metal.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent actionevent)
            {
                String plaf = "javax.swing.plaf.metal.MetalLookAndFeel";
                setWindowStyle(plaf);
                windows.setState(false);
                metal.setState(true);
            }
        });
        JMenuItem exit = new JMenuItem("退出");
        exit.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent arg0)
            {
                System.exit(0);
            }
        });
        
        windowStyle.add(windows);
        windowStyle.add(metal);
        windowStyle.addSeparator();
        windowStyle.add(exit);
        mb.add(windowStyle);
        
        // 菜单2
        JMenu help = new JMenu("帮助");
        JMenuItem use = new JMenuItem("使用指南");
        use.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent arg0)
            {
                JOptionPane.showMessageDialog(null,
                    "请按以下顺序操作：" + "\n 备份" + "\n 1. 选择项目源文件的目录。" + "\n 2. 选择需要备份的文件类型。" + "\n 3. 选择备份文件输出目录。" + "\n 4. 导出文件。" + "\n " + "\n 恢复 " + "\n 1. 到备份目录下选择备份文件。" + "\n 2. 选择备份文件的恢复目录。" + "\n 3. 恢复文件",
                    "使用指南",
                    JOptionPane.INFORMATION_MESSAGE);
            }
        });
        
        JMenuItem about = new JMenuItem("关于工具");
        about.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent arg0)
            {
                JOptionPane.showMessageDialog(null, "代码备份恢复工具，00fly 于2009年9月。", "关于本工具", JOptionPane.INFORMATION_MESSAGE);
            }
        });
        help.add(use);
        help.addSeparator();
        help.add(about);
        mb.add(help);
        setJMenuBar(mb);
    }
    
    // 根据字串设置窗口外观
    private void setWindowStyle(String plaf)
    {
        try
        {
            // 设定用户界面的外观
            UIManager.setLookAndFeel(plaf);
            // 将用户界面改成当前设定的外观
            SwingUtilities.updateComponentTreeUI(this);
        }
        catch (Exception e)
        {
        }
    }
    
    // 对话框
    class TheDialogAdapter extends WindowAdapter
    {
        Dialog d;
        
        public void init(Dialog d)
        {
            this.d = d;
        }
        
        @Override
        public void windowClosing(WindowEvent e)
        {
            d.setVisible(false);
        }
    }
    
    // 卡片
    class TabPanePanel extends JPanel implements ChangeListener
    {
        private static final long serialVersionUID = 7226393795721621635L;
        
        JTabbedPane jtp;
        
        BakPanl p1;
        
        RestorePanl p2;
        
        TabPanePanel()
        {
            jtp = new JTabbedPane();
            p1 = new BakPanl();
            p1.setVisible(true);
            p2 = new RestorePanl();
            p2.setVisible(true);
            jtp.addTab(" 代码备份 ", p1);
            jtp.addTab(" 代码恢复 ", p2);
            jtp.addChangeListener(this);
            setLayout(new BorderLayout());
            add(jtp, BorderLayout.CENTER);
        }
        
        @Override
        public void stateChanged(ChangeEvent e)
        {
            if (e.getSource() == jtp)
            {
                int i = ((JTabbedPane)e.getSource()).getSelectedIndex();
                if (i == 0)
                {
                    p1.setVisible(true);
                    p2.setVisible(false);
                }
                else
                {
                    p1.setVisible(false);
                    p2.setVisible(true);
                }
            }
        }
    }
    
    // 备份面板
    class BakPanl extends JPanel
    {
        
        private static final long serialVersionUID = 4050369107824321460L;
        
        // 界面组件
        JLabel sourceLabel = new JLabel("项目源文件目录:");
        
        JTextField tsourcePath = new JTextField(null, 45);
        
        JButton sourceBrowse = new JButton("选择");
        
        JLabel fileTypeLabel = new JLabel("源文件类型:");
        
        JCheckBox jb1 = new JCheckBox(".java", true);
        
        JCheckBox jb2 = new JCheckBox(".xml", true);
        
        JCheckBox jb3 = new JCheckBox(".yml", true);
        
        JCheckBox jb4 = new JCheckBox(".yaml", true);
        
        JCheckBox jb5 = new JCheckBox(".properties", true);
        
        JCheckBox jb6 = new JCheckBox(".sql", true);
        
        JCheckBox jb7 = new JCheckBox(".sh", true);
        
        JCheckBox jb8 = new JCheckBox(".htm", true);
        
        JCheckBox jb9 = new JCheckBox(".html", true);
        
        JCheckBox jb10 = new JCheckBox(".js", true);
        
        JCheckBox jb11 = new JCheckBox(".css", true);
        
        JCheckBox jb12 = new JCheckBox(".proto", true);
        
        JCheckBox jb13 = new JCheckBox(".vue", true);
        
        JCheckBox jb14 = new JCheckBox(".jsp", true);
        
        JCheckBox jb15 = new JCheckBox(".json", true);
        
        JCheckBox jb16 = new JCheckBox("Dockerfile", true);
        
        JLabel pwdLabel = new JLabel("可选项:");
        
        JButton pwdButton = new JButton("设置密码");
        
        JTextField tpwd = new JTextField(null, 10);
        
        JLabel bakeLabel = new JLabel("备份至目录:");
        
        JTextField tbakPath = new JTextField(null, 45);
        
        JButton bakBrowse = new JButton("选择");
        
        JButton bakButton = new JButton("开始备份");
        
        public BakPanl()
        {
            super();
            setLayout(null);
            setBackground(Color.WHITE);
            // 项目源文件路径
            sourceLabel.setBounds(20, 30, 120, 18);
            add(sourceLabel);
            tsourcePath.setFocusable(false);
            tsourcePath.setBounds(120, 30, 300, 20);
            add(tsourcePath);
            sourceBrowse.setBounds(430, 30, 70, 20);
            
            sourceBrowse.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    JFileChooser fc = new JFileChooser();
                    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    if (fc.showOpenDialog(null) == 1)
                    {
                        return;
                    }
                    else
                    {
                        // 新源文件目录被选中，清空密码
                        tpwd.setText(null);
                        File f = fc.getSelectedFile();
                        if (f.getPath().endsWith("\\"))
                        {
                            tsourcePath.setText(f.getAbsolutePath());
                        }
                        else
                        {
                            tsourcePath.setText(f.getAbsolutePath() + "\\");
                        }
                        pwdButton.setEnabled(true);
                    }
                }
            });
            add(sourceBrowse);
            
            // 文件类型
            fileTypeLabel.setBounds(20, 60, 120, 18);
            add(fileTypeLabel);
            jb1.setBounds(120, 60, 100, 18);
            jb1.setBackground(Color.WHITE);
            jb2.setBounds(120, 80, 100, 18);
            jb2.setBackground(Color.WHITE);
            jb3.setBounds(120, 100, 100, 18);
            jb3.setBackground(Color.WHITE);
            jb4.setBounds(120, 120, 100, 18);
            jb4.setBackground(Color.WHITE);
            jb5.setBounds(220, 60, 100, 18);
            jb5.setBackground(Color.WHITE);
            jb6.setBounds(220, 80, 100, 18);
            jb6.setBackground(Color.WHITE);
            jb7.setBounds(220, 100, 100, 18);
            jb7.setBackground(Color.WHITE);
            jb8.setBounds(220, 120, 100, 18);
            jb8.setBackground(Color.WHITE);
            jb9.setBounds(320, 60, 100, 18);
            jb9.setBackground(Color.WHITE);
            jb10.setBounds(320, 80, 100, 18);
            jb10.setBackground(Color.WHITE);
            jb11.setBounds(320, 100, 100, 18);
            jb11.setBackground(Color.WHITE);
            jb12.setBounds(320, 120, 100, 18);
            jb12.setBackground(Color.WHITE);
            jb13.setBounds(420, 60, 100, 18);
            jb13.setBackground(Color.WHITE);
            jb14.setBounds(420, 80, 100, 18);
            jb14.setBackground(Color.WHITE);
            jb15.setBounds(420, 100, 100, 18);
            jb15.setBackground(Color.WHITE);
            jb16.setBounds(420, 120, 100, 18);
            jb16.setBackground(Color.WHITE);
            add(jb1);
            add(jb2);
            add(jb3);
            add(jb4);
            add(jb5);
            add(jb6);
            add(jb7);
            add(jb8);
            add(jb9);
            add(jb10);
            add(jb11);
            add(jb12);
            add(jb13);
            add(jb14);
            add(jb15);
            add(jb16);
            
            // 密码项
            pwdLabel.setBounds(20, 150, 120, 18);
            add(pwdLabel);
            pwdButton.setBounds(120, 150, 100, 20);
            pwdButton.setEnabled(false);
            pwdButton.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    try
                    {
                        String pwd = JOptionPane.showInputDialog(null, "请输入8位密码（包括字母，数字和字符）：", "带密码备份", JOptionPane.INFORMATION_MESSAGE).trim();
                        if (!"".equals(pwd.trim()) && pwd.length() == 8)
                        {
                            // 设置密码
                            tpwd.setText(pwd);
                            JOptionPane.showMessageDialog(null, "密码设置成功！", "提示", JOptionPane.INFORMATION_MESSAGE);
                        }
                        else
                        {
                            // 清空密码
                            tpwd.setText(null);
                            JOptionPane.showMessageDialog(null, "密码设置失败！", "警告", JOptionPane.WARNING_MESSAGE);
                        }
                    }
                    catch (Exception e)
                    {
                        // 清空密码
                        tpwd.setText(null);
                        JOptionPane.showMessageDialog(null, "密码设置失败！", "警告", JOptionPane.WARNING_MESSAGE);
                    }
                }
            });
            add(pwdButton);
            add(tpwd);
            
            // 备份目录
            bakeLabel.setBounds(20, 180, 120, 18);
            add(bakeLabel);
            tbakPath.setBounds(120, 180, 300, 20);
            tbakPath.setFocusable(false);
            tbakPath.setText(new File(" ").getAbsolutePath().trim());
            add(tbakPath);
            bakBrowse.setBounds(430, 180, 70, 20);
            bakBrowse.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    JFileChooser fc = new JFileChooser(new File("").getAbsoluteFile());
                    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    if (fc.showOpenDialog(null) == 1)
                    {
                        return;
                    }
                    else
                    {
                        File f = fc.getSelectedFile();
                        if (f.getPath().endsWith("\\"))
                        {
                            tbakPath.setText(f.getAbsolutePath());
                        }
                        else
                        {
                            tbakPath.setText(f.getAbsolutePath() + "\\");
                        }
                    }
                }
            });
            add(bakBrowse);
            
            bakButton.setBounds(220, 220, 100, 30);
            bakButton.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    if (!"".equals(tsourcePath.getText()))
                    {
                        String sourcePath = tsourcePath.getText();
                        String bakFileName = tbakPath.getText() + new File(sourcePath).getName() + DateUtil.getCurrDateTimeStr() + ".bak";
                        List<String> list = new ArrayList<String>();
                        if (jb1.isSelected())
                        {
                            list.add(".java");
                        }
                        if (jb2.isSelected())
                        {
                            list.add(".xml");
                        }
                        if (jb3.isSelected())
                        {
                            list.add(".yml");
                        }
                        if (jb4.isSelected())
                        {
                            list.add(".yaml");
                        }
                        if (jb5.isSelected())
                        {
                            list.add(".properties");
                        }
                        if (jb6.isSelected())
                        {
                            list.add(".sql");
                        }
                        if (jb7.isSelected())
                        {
                            list.add("sh");
                        }
                        if (jb8.isSelected())
                        {
                            list.add(".htm");
                        }
                        if (jb9.isSelected())
                        {
                            list.add(".html");
                        }
                        if (jb10.isSelected())
                        {
                            list.add(".js");
                        }
                        if (jb11.isSelected())
                        {
                            list.add(".css");
                        }
                        if (jb12.isSelected())
                        {
                            list.add(".proto");
                        }
                        if (jb13.isSelected())
                        {
                            list.add(".vue");
                        }
                        if (jb14.isSelected())
                        {
                            list.add(".jsp");
                        }
                        if (jb15.isSelected())
                        {
                            list.add(".json");
                        }
                        if (jb16.isSelected())
                        {
                            list.add("Dockerfile");
                        }
                        try
                        {
                            Service service = new Service();
                            String pwdtext = tpwd.getText();
                            service.setSourcePath(sourcePath);
                            service.createBakFile(sourcePath, bakFileName, list, pwdtext);
                            String message = "创建明文备份文件 " + bakFileName + " 成功！";
                            
                            if (!"".equals(pwdtext))
                            {
                                message = "创建加密备份文件 " + bakFileName + " 成功！";
                            }
                            JOptionPane.showMessageDialog(null, message);
                        }
                        catch (RuntimeException e)
                        {
                            e.printStackTrace();
                            JOptionPane.showMessageDialog(null, "创建备份文件 " + bakFileName + " 失败！", "错误", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                    else
                    {
                        JOptionPane.showMessageDialog(null, "项目源文件目录不可为空!", "警告", JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                }
            });
            add(bakButton);
        }
    }
    
    // 恢复面板
    class RestorePanl extends JPanel
    {
        
        private static final long serialVersionUID = -4960976746526411789L;
        
        // 界面组件
        JLabel bakeLabel = new JLabel("选择备份文件:");
        
        JTextField tbakPath = new JTextField(null, 45);
        
        JButton bakBrowse = new JButton("选择");
        
        JLabel sourceLabel = new JLabel("恢复至目录:");
        
        JTextField tsourcePath = new JTextField(null, 45);
        
        JButton sourceBrowse = new JButton("选择");
        
        JButton resetButton = new JButton("开始恢复");
        
        public RestorePanl()
        {
            super();
            setLayout(null);
            // Label
            bakeLabel.setBounds(20, 30, 120, 18);
            add(bakeLabel);
            // Text
            tbakPath.setBounds(120, 30, 300, 20);
            tbakPath.setFocusable(false);
            add(tbakPath);
            // Button
            bakBrowse.setBounds(430, 30, 70, 20);
            bakBrowse.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    JFileChooser fc = new JFileChooser(new File("").getAbsoluteFile());
                    fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
                    if (fc.showOpenDialog(null) == 1)
                    {
                        return;
                    }
                    else
                    {
                        File f = fc.getSelectedFile();
                        tbakPath.setText(f.getAbsolutePath());
                    }
                }
            });
            add(bakBrowse);
            
            // Label
            sourceLabel.setBounds(20, 100, 120, 18);
            add(sourceLabel);
            // Text
            tsourcePath.setBounds(120, 100, 300, 20);
            tsourcePath.setFocusable(false);
            tsourcePath.setText(new File(" ").getAbsolutePath().trim());
            add(tsourcePath);
            // Button
            sourceBrowse.setBounds(430, 100, 70, 20);
            sourceBrowse.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    JFileChooser fc = new JFileChooser();
                    fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    if (fc.showOpenDialog(null) == 1)
                    {
                        return;
                    }
                    else
                    {
                        File f = fc.getSelectedFile();
                        if (f.getPath().endsWith("\\"))
                        {
                            tsourcePath.setText(f.getAbsolutePath());
                        }
                        else
                        {
                            tsourcePath.setText(f.getAbsolutePath() + "\\");
                        }
                    }
                }
            });
            add(sourceBrowse);
            
            // 恢复
            resetButton.setBounds(220, 170, 100, 30);
            resetButton.addActionListener(new ActionListener()
            {
                @Override
                public void actionPerformed(ActionEvent arg0)
                {
                    if ("".equals(tbakPath.getText()) || "".equals(tsourcePath.getText()))
                    {
                        JOptionPane.showMessageDialog(null, "备份文件或恢复目录不可为空!", "警告", JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    else
                    {
                        String dir = tsourcePath.getText();
                        try
                        {
                            new Service().createSourceFile(tbakPath.getText(), dir);
                            JOptionPane.showMessageDialog(null, "恢复文件到目录: " + dir + " 成功！");
                        }
                        catch (RuntimeException e)
                        {
                            JOptionPane.showMessageDialog(null, "恢复文件失败，请重新检查备份文件参数！", "错误", JOptionPane.ERROR_MESSAGE);
                        }
                    }
                }
            });
            add(resetButton);
        }
    }
    
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> new ProCodeToolFrame());
    }
}
